/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package actioncombination.logic.rlmethod;

import actioncombination.common.value.DoubleValue;
import actioncombination.common.value.Value;
import actioncombination.logic.agent.action.Action;
import actioncombination.logic.agent.AgentState;
import actioncombination.logic.agent.RLAgent;
import actioncombination.problem.gridworld.AgentStateImpl;
import actioncombination.logic.environment.RLEnvironment;
import actioncombination.logic.policy.PolicyStrategy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
 *
 * @author Administrador
 */
public class TD extends RLMethodStrategy {

    public TD(PolicyStrategy polStrategy) {
        super(polStrategy);
    }
    
    @Override
     public void beginEpisode(RLAgent agent){
        AgentStateImpl state= (AgentStateImpl) agent.getAgentState();
        state.initState();            
        while(!agent.getGoal().isGoalState(state)){
            step(agent);
        }
        endEpisode();
    }
    
    
    protected void step(RLAgent agent) {
        Map<AgentState, Value> valuesStates=new HashMap<AgentState, Value>();
        Collection<AgentState> nextPosibleActionStates=agent.getNextPosiblesActionsStates();
        AgentState oldState= agent.getAgentState();
        //cargo en valuesStates las posibles acciones que puedo tomar
        //y los estados hacia los que me llevan
        for(AgentState state: nextPosibleActionStates){
            valuesStates.put(state, state.getValue());
        }
        //elijo la accion dada por la politica para el estado actual y observo el nuevo estado
        AgentState newState=this.getPolStrategy().selectAction(valuesStates);
        //actualizo el estado del agente con el elegido por la politica
        agent.setState(newState);
        //observo la recompensa del nuevo estado
        DoubleValue reward=((RLEnvironment)agent.getEnvironment()).getReward(agent);
        //actualizo el viejo estado con la formula de actualizacion
        agent.update(oldState, newState, this.getLearningStep(), reward, this.getDiscountRate());
              
    }

    @Override
    protected void endEpisode() {
        
    }

  
}
